package com.stlm2.util;

import com.stlm2.core.id.RandomId;
import org.apache.commons.lang.time.DateUtils;
import org.apache.http.NameValuePair;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

public class Convert {

    static SimpleDateFormat FshortYMD = new SimpleDateFormat("yyyy-MM-dd");

    public static String toShortYMD(Date d) {
        if (d == null)
            return "";
        return FshortYMD.format(d);
    }

    static SimpleDateFormat FshortYMDPointSplit = new SimpleDateFormat("yyyy.MM.dd");

    public static String toShortYMDPointSplit(Date d) {
        if (d == null)
            return "";
        return FshortYMDPointSplit.format(d);
    }

    static SimpleDateFormat FshortYMDNoSplit = new SimpleDateFormat("yyyyMMdd");

    public static String toShortYMDWithNoSplit(Date d) {
        if (d == null)
            return "";

        return FshortYMDNoSplit.format(d);
    }

    static SimpleDateFormat FfullYMDHMSNoSplit = new SimpleDateFormat("yyyyMMddHHmmss");

    public static Date fromFullYMDHMSWithNoSplit(String d) {
        if (d == null)
            return null;

        try {
            return FfullYMDHMSNoSplit.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    static SimpleDateFormat YM = new SimpleDateFormat("yyyy-MM");

    public static String toYM(Date d) {
        if (d == null)
            return "";
        return YM.format(d);
    }

    static SimpleDateFormat FfulYMD = new SimpleDateFormat(
            "yyyy-MM-dd HH:mm:ss");

    public static String toFullYMDHMS(Date d) {
        if (d == null)
            return "";
        return FfulYMD.format(d);
    }

    static SimpleDateFormat FfulYMDWithNoSpace = new SimpleDateFormat(
            "yyyy-MM-dd-HH:mm:ss");

    public static String toFullYMDHMSWithNoSpace(Date d) {
        if (d == null)
            return "";
        return FfulYMDWithNoSpace.format(d);
    }

    static SimpleDateFormat FfulYMDWithNoSplit = new SimpleDateFormat(
            "yyyyMMddHHmmss");

    public static String toFullYMDHMSWithNoSplit(Date d) {
        if (d == null)
            return "";

        return FfulYMDWithNoSplit.format(d);
    }

    static SimpleDateFormat FYMDHM = new SimpleDateFormat("yyyy-MM-dd HH:mm");

    public static String toYMDHM(Date d) {
        if (d == null)
            return "";
        return FYMDHM.format(d);
    }

    static SimpleDateFormat FYMDHMS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static String toYMDHMS(Date d) {
        if (d == null)
            return "";
        return FYMDHMS.format(d);
    }

    public static  Date toDateYMDHMS(String d){
        if (d == null)
            return null;

        try {
            return FfullYMDHMSNoSplit.parse(d);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    static SimpleDateFormat CHINESEYMD = new SimpleDateFormat("yyyy年MM月dd日");

    public static String toChineseYMD(Date d) {
        if (d == null)
            return "";

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        return CHINESEYMD.format(d);
    }

    static SimpleDateFormat CHINESEYMDH = new SimpleDateFormat("yyyy年MM月dd日HH点");

    public static String toChineseYMDH(Date d) {
        if (d == null)
            return "";

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        return CHINESEYMDH.format(d);
    }

    static SimpleDateFormat CHINESEYMDHM = new SimpleDateFormat(
            "yyyy年MM月dd日HH点mm分");

    public static String toChineseYMDHM(Date d) {
        if (d == null)
            return "";

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(d);

        return CHINESEYMDHM.format(d);
    }

    /**
     * 把字符串表示的时间信息,转换为时间对象 字符串格式支持如下 yyyy-MM-ddThh:mi:ss.SSSZ
     * yyyy-MM-ddThh:mi:ss.SSS yyyy-MM-dd hh:mi:ss yyyy-MM-dd hh:mi yyyy-MM-dd
     * hh yyyy-MM-dd yyyy-MM yyyy
     *
     * @param datastr
     * @return
     */
    public static Calendar toCalendar(String datastr) {
        if (datastr == null || datastr.equals(""))
            return null;

        int y = 0, m = 0, d = 0, h = 0, mi = 0, s = 0, n = 0;
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.YEAR, y);
        cal.set(Calendar.MONTH, m - 1);
        cal.set(Calendar.DAY_OF_MONTH, d);
        cal.set(Calendar.HOUR_OF_DAY, h);
        cal.set(Calendar.MINUTE, mi);
        cal.set(Calendar.SECOND, s);
        cal.set(Calendar.MILLISECOND, n);

        datastr = datastr.trim();

        int p = 0, q;
        // yyyy-...
        q = datastr.indexOf('-', p);
        if (q <= 0) {
            y = Integer.parseInt(datastr);
            cal.set(Calendar.YEAR, y);
            return cal;
        }

        y = Integer.parseInt(datastr.substring(p, q));
        cal.set(Calendar.YEAR, y);

        p = q + 1;
        // yyyy-mm-...
        q = datastr.indexOf('-', p);
        if (q < 0) {
            m = Integer.parseInt(datastr.substring(p));
            cal.set(Calendar.MONTH, m - 1);
            cal.set(Calendar.DAY_OF_MONTH, 1);
            return cal;
        }

        m = Integer.parseInt(datastr.substring(p, q));
        cal.set(Calendar.MONTH, m - 1);

        p = q + 1;
        // yyyy-mm-dd ...
        q = datastr.indexOf(' ', p);
        if (q < 0)
            q = datastr.indexOf('T', p);
        if (q < 0) {
            d = Integer.parseInt(datastr.substring(p));
            cal.set(Calendar.DAY_OF_MONTH, d);
            return cal;
        }

        d = Integer.parseInt(datastr.substring(p, q));
        cal.set(Calendar.DAY_OF_MONTH, d);

        p = q + 1;
        // yyyy-mm-dd hh:...
        q = datastr.indexOf(':', p);
        if (q < 0) {
            h = Integer.parseInt(datastr.substring(p));
            cal.set(Calendar.HOUR_OF_DAY, h);
            return cal;
        }

        h = Integer.parseInt(datastr.substring(p, q).trim());
        cal.set(Calendar.HOUR_OF_DAY, h);

        p = q + 1;
        // yyyy-mm-dd hh:mi:...
        q = datastr.indexOf(':', p);
        if (q < 0) {
            mi = Integer.parseInt(datastr.substring(p));
            cal.set(Calendar.MINUTE, mi);
            return cal;
        }

        mi = Integer.parseInt(datastr.substring(p, q));
        cal.set(Calendar.MINUTE, mi);

        p = q + 1;
        // yyyy-mm-dd hh:mi:ss...
        q = datastr.indexOf('.', p);
        if (q < 0) {
            s = Integer.parseInt(datastr.substring(p).trim());
            cal.set(Calendar.SECOND, s);
            return cal;
        }

        s = Integer.parseInt(datastr.substring(p, q));
        cal.set(Calendar.SECOND, s);

        p = q + 1;
        // yyyy-mm-dd hh:mi:ss.ns
        String tmps = datastr.substring(p);
        if (tmps.length() >= 3) {
            n = Integer.parseInt(datastr.substring(p, p + 3).trim());
            cal.set(Calendar.MILLISECOND, n);
        }

        // ss.+0800
        if (tmps.length() == 8) {// zone
            int zmillis = Integer.parseInt(tmps.substring(4, 6)) * 3600000
                    + Integer.parseInt(tmps.substring(6, 8)) * 60000;

            if (tmps.charAt(3) == '-')
                zmillis = -zmillis;

            cal.set(Calendar.ZONE_OFFSET, zmillis);
        }

        // System.out.println("input="+datastr+" output="+sdf.format(cal.getTime()));
        return cal;
    }

    /**
     * 对输入的Plain文本转换成html文本,以适合页面输出展示的需要
     *
     * @param input
     * @return
     */
    public static String plainToHtml(String input) {
        if (input == null) {
            return "";
        }

        char[] array = input.toCharArray();

        StringBuffer buf = new StringBuffer(array.length + array.length / 2);

        for (int i = 0; i < array.length; i++) {

            switch (array[i]) {
                case '<':
                    buf.append("&lt;");
                    break;
                case '>':
                    buf.append("&gt;");
                    break;
                case '&':
                    buf.append("&amp;");
                    break;
                case '\n':
                    buf.append("<br/>");
                    break;
                case '\"':
                    buf.append("&#34;");
                    break;
                case '\'':
                    buf.append("&#39;");
                    break;
                default:
                    buf.append(array[i]);
                    break;
            }
        }
        return buf.toString();
    }

    public static String toBj(String s) {
        if (StringUtils.isNullOrTrimEmpty(s)) {
            return s;
        }

        try {
            int l = s.length();
            StringBuilder sb = new StringBuilder(l);
            String tmps = null;
            byte[] b = null;

            for (int i = 0; i < l; i++) {
                tmps = String.valueOf(s.charAt(i));
                b = tmps.getBytes("unicode");

                if (b[3] == -1) {
                    b[2] = (byte) (b[2] + 32);
                    b[3] = 0;

                    sb.append(new String(b, "unicode"));
                } else {
                    sb.append(tmps);
                }
            }
            return sb.toString();
        } catch (Exception e) {
        }
        return s;
    }

    /**
     * 隐藏手机号中间四位
     *
     * @param mobilePhone
     * @return
     */
    public static String toHiddenPhone(String mobilePhone) {
        if (StringUtils.isNullOrTrimEmpty(mobilePhone))
            return "";

        if (!StringUtils.isNum(mobilePhone) || mobilePhone.length() != 11)
            return mobilePhone.substring(0, 1) + "**";

        return mobilePhone.substring(0, 3) + "****" + mobilePhone.substring(7);
    }

    /**
     * 获得最前几位内容
     * 用于获得银行卡号后四位
     *
     * @return
     */
    public static String getFrontVal(String content, int length) {
        if (StringUtils.isNullOrTrimEmpty(content) || length <= 0)
            return "";

        if (length >= content.length())
            return content;
        else
            return content.substring(0, length);
    }

    /**
     * 获得最后几位内容
     * 用于获得银行卡号后四位
     *
     * @return
     */
    public static String getLastVal(String content, int length) {
        if (StringUtils.isNullOrTrimEmpty(content) || length <= 0)
            return "";

        if (length >= content.length())
            return content;
        else
            return content.substring(content.length() - length);
    }

    /**
     * 元 ---> 万元
     *
     * @param price
     * @return
     */
    public static double toWanYuan(double price) {
        return price / 10000;
    }

    /**
     * 万元 ----> 元
     *
     * @param price
     * @return
     */
    public static int toYuan(double price) {
        return (int) (price * 10000);
    }

    public static Date beforeMinute(Date date, int minute) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.MINUTE, calendar.get(Calendar.MINUTE) - minute);
        return calendar.getTime();
    }

    public static Date beforeHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, calendar.get(Calendar.HOUR_OF_DAY) - hour);
        return calendar.getTime();
    }

    public static Date afterDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH)
                + day);
        return calendar.getTime();
    }

    public static Date beforeDay(Date date, int day) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DAY_OF_MONTH, calendar.get(Calendar.DAY_OF_MONTH)
                - day);
        return calendar.getTime();
    }

    public static String getTimeDiff(Date date) {
        Calendar cal = Calendar.getInstance();
        long diff = 0;
        Date dnow = cal.getTime();
        String str = "";
        diff = Math.abs(dnow.getTime() - date.getTime());

        long day = diff / (24 * 60 * 60 * 1000);
        long hour = (diff / (60 * 60 * 1000) - day * 24);
        long min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);

        return day + "天" + hour + "时" + min + "分";
    }

    public static String getTimeDiffSecond(Date startDate, Date endDate) {
        long diff = 0;
        String str = "";
        diff = Math.abs(endDate.getTime() - startDate.getTime());

        long day = diff / (24 * 60 * 60 * 1000);
        long hour = (diff / (60 * 60 * 1000) - day * 24);
        long min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);
        long second = ((diff / 1000) - day * 24 * 60 * 60 - hour*60*60  - min*60);

        return day + "天" + hour + "时" + min + "分" + second + "秒";
    }

    /**
     *
     * @param date
     * @return 7-22-8 == 7天22时8分
     */
    public static String getTimeDiffSpiltRung(Date date) {
        Calendar cal = Calendar.getInstance();
        long diff = 0;
        Date dnow = cal.getTime();
        String str = "";
        diff = Math.abs(dnow.getTime() - date.getTime());

        long day = diff / (24 * 60 * 60 * 1000);
        long hour = (diff / (60 * 60 * 1000) - day * 24);
        long min = ((diff / (60 * 1000)) - day * 24 * 60 - hour * 60);

        return day + "-" + hour + "-" + min;
    }

    /**
     * 获取两个日期相差的天数
     *
     * @param date1
     * @param date2
     * @return
     */
    public static Long getDaysDiff(Date date1, Date date2) {
        return Math.abs(DateUtils.truncate(date2, Calendar.DAY_OF_MONTH).getTime() / 86400000 - DateUtils.truncate(date1, Calendar.DAY_OF_MONTH).getTime() / 86400000);
    }

    /**
     * 获得年龄
     *
     * @param date
     * @return
     */
    public static int getAge(Date date) {
        if (date == null)
            return 0;

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        int start = calendar.get(Calendar.YEAR);

        calendar.setTime(new Date());
        int end = calendar.get(Calendar.YEAR);
        return end - start;
    }

    /**
     *  获取星期几
     * @param dt
     * @return
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;
        return weekDays[w];
    }

    /**
     *  获取星期几
     * @param dt
     * @return
     */
    public static int WeekOfDate(Date dt) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);
        return cal.get(Calendar.DAY_OF_WEEK)-1 ;
    }
    /**
     * 转换为小数
     *
     * @param num       原数值
     * @param precision 转换后的精度（金币为2位精度，金额为2位精度）
     * @return
     */
    public static double toDecimal(int num, int precision) {
        return Double.parseDouble(toDecimalStr(num, precision));
    }

    /**
     * 转换为小数
     *
     * @param num       原数值
     * @param precision 转换后的精度（金币为2位精度，金额为2位精度）
     * @return
     */
    public static String toDecimalStr(int num, int precision) {
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(precision);
        df.setGroupingSize(0);
        df.setRoundingMode(RoundingMode.FLOOR);
        return df.format(num / Math.pow(10, precision));
    }

    /**
     * 转换为小数
     *
     * @param num       原数值
     * @param precision 转换后的精度（金币为2位精度，金额为2位精度）
     * @return
     */
    public static double toDecimal(long num, int precision) {
        return Double.parseDouble(toDecimalStr(num, precision));
    }

    /**
     * 转换为小数
     *
     * @param num       原数值
     * @param precision 转换后的精度（金币为2位精度，金额为2位精度）
     * @return
     */
    public static String toDecimalStr(long num, int precision) {
        DecimalFormat df = new DecimalFormat();
        df.setMaximumFractionDigits(precision);
        df.setGroupingSize(0);
        df.setRoundingMode(RoundingMode.FLOOR);
        return df.format(num / Math.pow(10, precision));
    }

    /**
     * 小数转换为整数
     *
     * @param num
     * @param precision
     * @return
     */
    public static int fromDecimal(double num, int precision) {
        return (int) (num * Math.pow(10, precision));
    }

    /**
     * 小数转换为整数
     *
     * @param num
     * @param precision
     * @return
     */
    public static long fromDecimalToLong(double num, int precision) {
        return (long) (num * Math.pow(10, precision));
    }
    /**
     * String转换为Long
     * @authon fuchunyu
     * @param num   金额
     * @param precision    位数
     * @return long
     */
    public static long DecimalToLong(String num, int precision) {
        return new BigDecimal(num).multiply(new BigDecimal(Math.pow(10, precision))).longValue();
    }


    /**
     * Double转换为Long
     * @authon fuchunyu
     * @param num   金额
     * @param precision    位数
     * @return long
     */
    public static long DecimalToLong(double num, int precision) {
        return new BigDecimal(num).multiply(new BigDecimal(Math.pow(10, precision))).longValue();
    }

    /**
     * String转换为BigDecimal
    * @authon fuchunyu
    * @param num   金额
    * @param precision    位数
    * @return BigDecimal
    */
    public static BigDecimal DecimalForString(String num, int precision) {
        return new BigDecimal(num).multiply(new BigDecimal(Math.pow(10, precision)));
    }
    /**
     * 获得订单号
     *
     * @param type
     * @param id
     * @return
     */
    public static String getOrderCode(String type, long id) {
        if (StringUtils.isNullOrTrimEmpty(type))
            return String.valueOf(id);

        return type + RandomId.randomId(id);
    }

    /**
     * 获得订单号
     *
     * @param type
     * @param id
     * @return
     */
    public static String getOrderCode(int type, long id) {
        String _type = String.valueOf(type);
        if (type < 10)
            _type = "0" + _type;

        return getOrderCode(String.valueOf(_type), id);
    }

    /**
     * 将键值对转为map
     *
     * @param map
     * @return
     */
    public static Map<String, String> mapConvert(Map<String, String[]> map) {
        Map<String, String> result = new HashMap<String, String>();
        if (map != null && map.size() > 0) {
            for (String key : map.keySet()) {
                result.put(key, map.get(key)[0]);
            }
        }
        return result;
    }

    /**
     * 将键值对转为map
     *
     * @param nameValuePairs
     * @return
     */
    public static Map<String, String> nameValuePairToMap(List<NameValuePair> nameValuePairs) {
        Map<String, String> result = new HashMap<String, String>();
        if (nameValuePairs != null && nameValuePairs.size() > 0) {
            for (NameValuePair nameValuePair : nameValuePairs) {
                result.put(nameValuePair.getName(), nameValuePair.getValue());
            }
        }
        return result;
    }




    public static boolean isSame(String str){
        String	regex = str.substring(0,1)+"{"+str.length()+"}";
        return str.matches(regex);
    }


    public static List<Date> getAllDateOfTheMonth(Date date) {
        List<Date> list = new ArrayList<Date>();
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.DATE, 1);
        int month = cal.get(Calendar.MONTH);
        while(cal.get(Calendar.MONTH) == month){
            list.add(cal.getTime());
            cal.add(Calendar.DATE, 1);
        }
        return list;
    }

    public static void main(String[] args) {

        System.out.println(Convert.toFullYMDHMS(Convert.beforeHour(new Date(), 12)));

        System.out.println(1255756.50 + 25007.00 + 937572.50 + 102144.50 + 49806.50 + 13817.50 + 67599.00 + 37007.00);

        System.out.println(1407524.00 + 27916.00 + 1051207.00 + 113103.00 + 56210.00 + 15722.00 + 75684.00 + 41732.00);

    }

}
